package com.xhorse.lockplatform.comm.mvc;

import com.xhorse.lockplatform.comm.model.BaseId;
import com.xhorse.lockplatform.comm.model.BaseQuery;
import com.xhorse.lockplatform.comm.service.BaseService;
import com.xhorse.lockplatform.comm.util.Paginator;
import com.xhorse.lockplatform.comm.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * 实现列表的控制器
 *
 * @author Tom
 */
public abstract class AbstractListController<T extends BaseId, S extends BaseService<T>, Q extends BaseQuery> {
    protected final Logger log = LoggerFactory.getLogger(getClass());

    protected final String NAV_LIST_PAGE;
    protected final String LIST_PAGE;
    protected S service;
    protected List<T> data;

    public AbstractListController(String model) {
        NAV_LIST_PAGE = String.format("%s/list", model);
        LIST_PAGE = String.format("/%s/list", model);
    }

    @RequestMapping("/list")
    public String list(Q query, BindingResult errors, Model model, HttpServletRequest request) {
        int page = getPage(request);
        return innerList(page > 0 ? page : 1, query, model);
    }

    private int getPage(HttpServletRequest request) {
        String page = request.getParameter("_page");
        if (page == null || page.isEmpty() || "undefined".equals(page)) {
            return -1;
        }
        try {
            return Integer.valueOf(page);
        } catch (Exception e) {
            //do nothing
            throw e;
        }
    }

    @RequestMapping("/list/{page}")
    public String list(@PathVariable("page") int page, Q query, BindingResult errors, Model model) {
        return innerList(page, query, model);
    }

    protected Paginator makePaginator(int page, Q query) {
        Paginator paginator = new Paginator(page);
        query.setPageSize(query.getPageSize());
        paginator.setQuery(query);
        paginator.setPath(NAV_LIST_PAGE);
        return paginator;
    }

    private String innerList(int page, Q query, Model model) {
        Paginator paginator = makePaginator(page, query);
        paginator.setSize(Integer.valueOf(StringUtil.isNotNil(query.getPageSize()) ? query.getPageSize() : "12"));
        boolean expectHasData = preList(page, paginator, query, model);
        List<T> datas = Collections.emptyList();
        if (expectHasData) {
            datas = data;
        }
        model.addAttribute("datas", datas);
        model.addAttribute("paginator", paginator);
        model.addAttribute("hasDatas", datas != null && !datas.isEmpty());
        postList(page, paginator, query, model);
        return LIST_PAGE;
    }

    protected void postList(int page, Paginator paginator, Q query, Model model) {
    }

    /**
     * 如果返回true，表示预测有数据，false，则预测没有数据，直接跳过数据查询
     *
     * @param page
     * @param query
     * @param model
     * @return
     */
    protected boolean preList(int page, Paginator paginator, Q query, Model model) {
        return true;
    }
}
